<?php

declare(strict_types=1);

namespace app\common\lib\easywechat;

use liang\MicroEngine;
use EasyWeChat\Factory;

/**
 * 微信支付
 */
class Payment
{
    public $app;

    /**
     * 初始化配置
     */
    public function __construct()
    {
        // 获取支付配置
        MicroEngine::getPaymentConfig($app_id, $mch_id, $key, $cert_path, $key_path);
        $config = [
            // 必要配置
            'app_id'             => $app_id,
            'mch_id'             => $mch_id,
            'key'                => $key,   // API 密钥

            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            'cert_path'          => $cert_path, // XXX: 绝对路径！！！！
            'key_path'           => $key_path,      // XXX: 绝对路径！！！！
            'notify_url'         => '默认的订单回调地址',     // 你也可以在下单时单独设置来想覆盖它
        ];
        $this->app = Factory::payment($config);
    }

    // +---------------------------------------------------------------------
    // | 统一下单
    // +---------------------------------------------------------------------
    // | https://easywechat.com/docs/4.x/payment/order 生成预支付交易单
    // +---------------------------------------------------------------------
    // | https://easywechat.com/docs/4.x/payment/jssdk 生成支付 JS 配置
    // +---------------------------------------------------------------------

    /**
     * 生成预支付交易单
     * 
     * @return string WeixinJSBridge 调起支付所需的JS配置
     */
    public function unify($openid, $total_fee, $body)
    {
        // 生成预支付交易单
        try {
            $result = $this->app->order->unify([
                'body'             => $body,
                'out_trade_no'     => $this->ordersn(),
                'total_fee'        => $total_fee,
                'notify_url'       => 'https://pay.weixin.qq.com/wxpay/pay.action',   // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                'trade_type'       => 'JSAPI',                                        // 请对应换成你的支付方式对应的值类型
                'openid'           => $openid,
            ]);
            event('unify', $result);
        } catch (\Exception $e) {
            $msg  = $e->getMessage();
            event('unify', compact('msg'));
            fault('下单失败');
        }
        // 判断预支付交易单是否生成成功
        if (isset($result['result_code']) && $result['result_code'] === 'SUCCESS') {
            // 预支付交易单生成成功
            $prepayId = $result['prepay_id'];
            $bridgeConfig = $this->app->jssdk->bridgeConfig($prepayId);
            // event('unify', compact('bridgeConfig'));
            return ['payParams' => $bridgeConfig];
        } else {
            // 预支付交易单生成失败
            fault('订单创建失败');
        }
    }

    /**
     * 随机生成18位数字订单号 (18位:不包含前缀)
     * 
     * @param string $prefix 订单号前缀
     */
    public function ordersn(string $prefix = '')
    {
        return $prefix . date('YmdHis') . substr(implode('', array_map('ord', str_split(substr(uniqid(), 7,  13), 1))), 0, 2) . mt_rand(10, 99);
    }
}
